#pragma once
#include <iostream>
#include "Socket.hpp"
#include "Inetaddr.hpp"
#include "HandlerConnection.hpp"
class Listener
{
public:
    Listener(int port, HandlerConnection &hc) : _port(port), _listensock(std::make_unique<socket_ns::TcpSocket>()), _hc(hc)
    {
        InetAddr addr("0", _port);
        _listensock->BuildListenSocket(addr);
    }
    ~Listener()
    {
        _listensock->Close();
    }
    void Accepter(std::shared_ptr<Connection> conn)
    {
        while (true)
        {
            InetAddr client_addr;
            int code = 0;
            socket_ns::socket_ptr sock = _listensock->Accepter(&client_addr, &code);
            if (sock->Sockfd() < 0)
            {
                if (code == EWOULDBLOCK || code == EAGAIN)
                {
                    // 底层链接读取完了
                    DLOG("accept all link!");
                    break;
                }
                else if (code == EINTR)
                {
                    // 信号中断了
                    DLOG("aceept interrupt by signal!");
                    continue;
                }
                else
                {
                    ELOG("accept error!");
                }
            }
            else
            {
                conn->_R->AddConnection(sock, EPOLLIN | EPOLLET,
                                        std::bind(&HandlerConnection::HandlerRecv, &_hc, std::placeholders::_1),
                                        std::bind(&HandlerConnection::HandlerSend, &_hc, std::placeholders::_1),
                                        std::bind(&HandlerConnection::HanlderExcept, &_hc, std::placeholders::_1));
            }
        }
    }
    socket_ns::socket_ptr ListenSock()
    {
        return _listensock;
    }

private:
    int _port;
    socket_ns::socket_ptr _listensock;
    HandlerConnection &_hc;
};